With the widespread use of the Internet as a programming vehicle, software developers are increasingly encountering circumstances in which their software interacts with individuals who either are unsophisticated in their use of computers or are malicious in their intent to gain access to remote computing systems. These programmers develop software modules which interact with and accept data from an infinite number of potential users. As such, the assumptions that users may be well-trained, or that users will behave in a particular manner, may not be well-founded.
One area in which an increasingly large number of situations where unsophisticated or malicious users may cause problems to software written for the Internet arises when software developers locate input data buffers within memory locations that are adjacent to a location containing instruction addresses. Typically this situation arises when return addresses are pushed onto a system stack where the system stack is also used as a location to store local variables for functions called during a program's operation.
In such a situation, a user may over write the input buffer by providing more data for storage within the buffer than the programmer has expected. Because programmers have typically allocated input buffers which are “more than large enough” to hold the expected data, the over writing of the input buffers results in the over writing of other memory locations containing other variables. When the other variables that are over written contain addresses for instructions, the behavior of the program in question is unpredictable as these over written addresses are used as to obtain instructions from incorrect locations.
Various methods to alleviate this situation have been suggested over time. First, a system that separates the address data from variable data in different places within memory has been suggested. With such an arrangement, the system would not be able to execute instructions based upon addresses stored within memory locations within the input buffer area. This arrangement is unsatisfactory as it would require a significant reallocation of the manner in which data and instructions are stored within the memory of a computing system. As such, newly written code may not be compatible with previously written modules.
Another method of eliminating this problem is to prevent the execution of instructions which are located within a system stack. This solution would eliminate the problem in which instructions are mistakenly or maliciously placed onto the stack for execution on a buffer is over written; however, the solution also requires a significant overhead associated with a mechanism that determines whether an instruction being fetched is stored on a system stack.
Any solution to this problem must provide a mechanism by which a buffer overrun circumstance is reliable detected while not imposing significant performance overhead requirements upon the processing modules that utilize the mechanism.